﻿Imports Kairyu.Connection
Imports System.Reflection

''' <summary>
''' DB用文字列整形
''' </summary>
''' <remarks>
''' #97　MySQL
''' DB用文字列加工処理を集約します
''' </remarks>
Public MustInherit Class StringFormConverter

    Public Shared Abbreviations As New Dictionary(Of String, String)

    Protected Sub New()
    End Sub

    Public Shared Sub SetInstance(c As StringFormConverter)
        If _instance IsNot Nothing Then Throw New InvalidOperationException("既にインスタンスされています。")
        _instance = c
    End Sub

    Private Shared _instance As StringFormConverter
    Public Shared Function Instance() As StringFormConverter
        If _instance Is Nothing Then
            If Connector.Instance.DBMS = DBMS.Oracle OrElse Connector.Instance.DBMS = DBMS.MySQL Then
                _instance = New SnakeCaseFormConverter
            Else
                _instance = New PluralFormConverter
            End If
        End If
        Return _instance
    End Function

    Public Overridable Function ToNameSpace(t As Type) As String
        If Connector.Instance.DBMS = DBMS.SqlCe Then Return String.Empty

        Dim nm As String = String.Empty

        If (From el As String In t.Namespace.Split(".") Where el = "Models").Any Then
            '名前空間の区切りに"Models"という単語が合った場合、以降の名前空間だけを処理対象とします
            Dim flg As Boolean = False
            For Each item As String In t.Namespace.Split(".")
                If flg Then nm &= IIf(nm = String.Empty, "", ".") & item
                If flg = False AndAlso item = "Models" Then flg = True
            Next
        Else
            'それ以外の場合、全ての名前空間が処理対象になります
            nm = String.Empty
        End If

        '処理対象名前空間が取得できなかった場合、空とします
        If String.IsNullOrEmpty(nm) Then Return String.Empty

        '処理対象名前空間の区切り数により、データベース名、スキーマ名を求めます
        Dim cnt As Integer = nm.Split(".").Count
        If 2 <= cnt Then
            Return String.Format("{0}.{1}", nm.Split(".")(cnt - 2), nm.Split(".")(cnt - 1))
        Else
            Return nm
        End If
    End Function

    ''' <summary>
    ''' テーブル名を取得します
    ''' </summary>
    ''' <param name="t"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overridable Function ToTable(t As Type) As String
        '#78　テーブル、列名の略称辞書を作る
        Dim s = t.Name
        For Each item In StringFormConverter.Abbreviations
            s = Replace(s, item.Key, item.Value)
        Next
        Return s
    End Function

    ''' <summary>
    ''' 列名を取得します
    ''' </summary>
    ''' <param name="prop"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ToColumn(prop As PropertyInfo) As String
        Return Me.ToColumn(prop.Name)
    End Function

    ''' <summary>
    ''' 列名を取得します
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overridable Function ToColumn(name As String) As String
        '略称辞書を用いて列名を求めます
        For Each item In StringFormConverter.Abbreviations
            name = Replace(name, item.Key, item.Value)
        Next
        Return name
    End Function

    Public Overridable Function ToPrefix(name As String) As String
        Return name
    End Function

    Public MustOverride Function Convert(name As String) As String

End Class
